From 179244ea3ea093c20c1912a1a9802f31afe504ea Mon Sep 17 00:00:00 2001 From: oliskoli Date: Fri, 5 Sep 2008 20:38:08 +0000 Subject: [PATCH] ggv_ovl: Add support for 'Geogrid viewer ascii overlay files. --- ggv_ovl.c | 440 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 440 insertions(+) create mode 100644 ggv_ovl.c diff --git a/ggv_ovl.c b/ggv_ovl.c new file mode 100644 index 000000000..75ffeb303 --- /dev/null +++ b/ggv_ovl.c @@ -0,0 +1,440 @@ +/* + + Support for "GeoGrid Viewer ascii overlay files". + + Copyright (C) 2008 Olaf Klein (o.b.klein@gpsbabel.org). + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include + +#include "defs.h" +#include "inifile.h" +#include "grtcirc.h" + +#define MYNAME "ggv_ovl" + +static +arglist_t ggv_ovl_args[] = { + ARG_TERMINATOR +}; + +typedef enum { + OVL_SYMBOL_BITMAP = 1, + OVL_SYMBOL_TEXT, + OVL_SYMBOL_LINE, + OVL_SYMBOL_POLYGON, + OVL_SYMBOL_RECTANGLE, + OVL_SYMBOL_CIRCLE, + OVL_SYMBOL_TRIANGLE +} OVL_SYMBOL_TYP; + +typedef enum { + OVL_COLOR_RED = 1, /* = 1 */ + OVL_COLOR_LIME, /* = 2 */ + OVL_COLOR_BLUE, /* = 3 */ + OVL_COLOR_YELLOW, /* = 4 */ + OVL_COLOR_BLACK, /* = 5 */ + OVL_COLOR_WHITE, /* = 6 */ + OVL_COLOR_7, /* = 7 (draws only a simple line) */ + OVL_COLOR_FUCHSIA, /* = 8 */ + OVL_COLOR_AQUA, /* = 9 */ +} OVL_COLOR_TYP; + +/* some hints: + # "col": color + # "group": 1 means NO GROUP + # "size": size in pixels PLUS 100 + # "with": + # "zoom": + # "art": line-style + */ +static inifile_t *inifile; +static gbfile *fout; + +static int symbol_ct; /* Number of symbols written */ +static int group_ct; /* Group number during write */ +static int track_ct, route_ct; +static bounds all_bounds; +static OVL_COLOR_TYP color; + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +ggv_ovl_rd_init(const char *fname) +{ + inifile = inifile_init(fname, MYNAME); + if (ini->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); + + route_ct = 0; + track_ct = 0; +} + +static void +ggv_ovl_rd_deinit(void) +{ + inifile_done(inifile); +} + +static void +ggv_ovl_read(void) +{ + int symbols; + int i; + + symbols = inifile_readint_def(inifile, "Overlay", "Symbols", -1); + + for (i = 1; i <= symbols; i++) { + int points; + OVL_SYMBOL_TYP type; + char symbol[32]; + + snprintf(symbol, sizeof(symbol), "Symbol %d", i); + + type = (OVL_SYMBOL_TYP) inifile_readint_def(inifile, symbol, "Typ", 0); + points = inifile_readint_def(inifile, symbol, "Punkte", -1); + + switch(type) { + + char coord[32]; + waypoint *wpt; + char *cx; + int group; + + case OVL_SYMBOL_LINE: + case OVL_SYMBOL_POLYGON: + + if (!inifile_readint(inifile, symbol, "Group", &group)) group = -1; + + if (points > 0) { + int j; + route_head *rte, *trk; + + rte = trk = route_head_alloc(); + if (group > 1) { + route_add_head(rte); + route_ct++; + xasprintf(&rte->rte_name, "Route %d", route_ct); + } + else { + track_add_head(trk); + track_ct++; + xasprintf(&trk->rte_name, "Track %d", track_ct); + } + + for (j = 0; j < points; j++) { + + wpt = waypt_new(); + + snprintf(coord, sizeof(coord), "YKoord%d", j); + if ((cx = inifile_readstr(inifile, symbol, coord))) + wpt->latitude = atof(cx); + else + continue; + + snprintf(coord, sizeof(coord), "XKoord%d", j); + if ((cx = inifile_readstr(inifile, symbol, coord))) + wpt->longitude = atof(cx); + else + continue; + + if (group > 1) route_add_wpt(rte, wpt); + else track_add_wpt(trk, wpt); + } + } + break; + + case OVL_SYMBOL_CIRCLE: + case OVL_SYMBOL_TRIANGLE: + + wpt = waypt_new(); + wpt->shortname = xstrdup(symbol); + + if ((cx = inifile_readstr(inifile, symbol, "YKoord"))) + wpt->latitude = atof(cx); + else + continue; + if ((cx = inifile_readstr(inifile, symbol, "XKoord"))) + wpt->longitude = atof(cx); + else + continue; + + waypt_add(wpt); + break; + + case OVL_SYMBOL_BITMAP: + case OVL_SYMBOL_TEXT: + case OVL_SYMBOL_RECTANGLE: break; + } + } +} + +/**************************************************************************/ + +/* prototypes used in main functions */ + +static void waypt_disp_cb(const waypoint *wpt); +static void track_disp_cb(const route_head *trk); +static void route_disp_cb(const route_head *rte); +static void write_bounds(void); +static void draw_symbol_basics(const OVL_SYMBOL_TYP typ, const int art, const OVL_COLOR_TYP color, const waypoint *wpt); +static int get_direction(const waypoint *A, const waypoint *B); +// static void draw_symbol_text(const char *text, const waypoint *reference); + +/* -----------------------------------------------------------------------*/ + +static void +ggv_ovl_wr_init(const char *fname) +{ + fout = gbfopen(fname, "w", MYNAME); + + symbol_ct = 0; +} + +static void +ggv_ovl_wr_deinit(void) +{ + gbfclose(fout); +} + +static void +ggv_ovl_write(void) +{ + group_ct = 1; /* tracks are not grouped */ + color = OVL_COLOR_FUCHSIA; + track_disp_all(track_disp_cb, NULL, NULL); + + group_ct++; + color = OVL_COLOR_AQUA; + route_disp_all(route_disp_cb, NULL, NULL); + + group_ct++; + color = OVL_COLOR_LIME; + waypt_disp_all(waypt_disp_cb); + + gbfprintf(fout, "[Overlay]\n"); + gbfprintf(fout, "Symbols=%d\n", symbol_ct); + gbfprintf(fout, "[MapLage]\n"); + gbfprintf(fout, "MapName=Bundesrepublik 1:1 Mio\n"); + gbfprintf(fout, "DimmFc=100\n"); + gbfprintf(fout, "ZoomFc=100\n"); + write_bounds(); + gbfprintf(fout, "RefOn=0\n"); /* no reference point */ +} + +/**************************************************************************/ + +static void +waypt_disp_cb(const waypoint *wpt) +{ + draw_symbol_basics(OVL_SYMBOL_CIRCLE, 1, color, wpt); + gbfprintf(fout, "Width=20\n"); + gbfprintf(fout, "Height=20\n"); + gbfprintf(fout, "Dir=100\n"); + gbfprintf(fout, "Zoom=1\n"); + gbfprintf(fout, "Size=102\n"); + gbfprintf(fout, "Area=2\n"); +// draw_symbol_text(wpt->shortname, wpt); +} + +/* -----------------------------------------------------------------------*/ + +static void +track_disp_cb(const route_head *trk) +{ + int i; + queue *elem, *tmp; + int waypt_ct = trk->rte_waypt_ct; + + if (waypt_ct <= 0) return; + + draw_symbol_basics(OVL_SYMBOL_LINE, 1, color, NULL); + + gbfprintf(fout, "Zoom=1\n"); + gbfprintf(fout, "Size=105\n"); + gbfprintf(fout, "Punkte=%d\n", waypt_ct); + + i = 0; + + QUEUE_FOR_EACH(&(trk->waypoint_list), elem, tmp) { + + waypoint *wpt = (waypoint *) elem; + + gbfprintf(fout, "XKoord%d=%0.8f\n", i, wpt->longitude); + gbfprintf(fout, "YKoord%d=%0.8f\n", i, wpt->latitude); + + i++; + } +} + +/* -----------------------------------------------------------------------*/ + +static void +route_disp_cb(const route_head *rte) +{ + int i; + queue *elem, *tmp; + waypoint *prev; + int waypt_ct = rte->rte_waypt_ct; + + if (waypt_ct <= 0) return; + + track_disp_cb(rte); /* draw a line as tracks */ + + color = OVL_COLOR_RED; + + i = 0; + prev = NULL; + + QUEUE_FOR_EACH(&(rte->waypoint_list), elem, tmp) { + + waypoint *wpt = (waypoint *) elem; + + if (prev != NULL) { + draw_symbol_basics(OVL_SYMBOL_TRIANGLE, 1, 9 /* color */, prev); + + gbfprintf(fout, "Width=12\n"); + gbfprintf(fout, "Height=8\n"); + gbfprintf(fout, "Dir=%d\n", 100 + get_direction(prev, wpt)); + gbfprintf(fout, "Zoom=1\n"); + gbfprintf(fout, "Size=101\n"); + gbfprintf(fout, "Area=2\n"); + } + + i++; + prev = wpt; + } +} + +/* -----------------------------------------------------------------------*/ + +static void +waypt_bound_calc(const waypoint *waypointp) +{ + waypt_add_to_bounds(&all_bounds, waypointp); +} + +static void +write_bounds(void) +{ + waypt_init_bounds(&all_bounds); + + waypt_disp_all(waypt_bound_calc); + route_disp_all(NULL, NULL, waypt_bound_calc); + track_disp_all(NULL, NULL, waypt_bound_calc); + + if (waypt_bounds_valid(&all_bounds)) { + + double cx = all_bounds.min_lat + ((all_bounds.max_lat - all_bounds.min_lat) / 2); + double cy = all_bounds.min_lon + ((all_bounds.max_lon - all_bounds.min_lon) / 2); + + gbfprintf(fout, "CenterLat=%0.8f\n", cx); + gbfprintf(fout, "CenterLong=%0.8f\n", cy); + } + else { + gbfprintf(fout, "CenterLong=10.52374295\n"); + gbfprintf(fout, "CenterLat=52.26474445\n"); + } +} + +static void +draw_symbol_basics(const OVL_SYMBOL_TYP typ, const int art, const OVL_COLOR_TYP color, const waypoint *wpt) +{ + symbol_ct++; + + gbfprintf(fout, "[Symbol %d]\n", symbol_ct); + gbfprintf(fout, "Typ=%d\n", typ); + gbfprintf(fout, "Group=%d\n", group_ct); + gbfprintf(fout, "Col=%d\n", color); + if (art >= 0) gbfprintf(fout, "Art=%d\n", art); + if (wpt) { + gbfprintf(fout, "XKoord=%.8f\n", wpt->longitude); + gbfprintf(fout, "YKoord=%.8f\n", wpt->latitude); + } +} + +/* the following code comes from first overlay module */ + +static int +get_direction(const waypoint *A, const waypoint *B) +{ + double lata, lona, latb, lonb; + double dist, dir; + int res; + + lata = RAD(A->latitude); + lona = RAD(A->longitude); + latb = RAD(B->latitude); + lonb = RAD(B->longitude); + + dist = gcdist(lata, lona, latb, lonb); + dir = acos((sin(latb) - sin(lata) * cos(dist)) / (cos(lata) * sin(dist))); + if (lonb < lona) dir = -dir; + res = (int) DEG(dir); + res = 360 - (res + 270); + if (res < 0) res += 360; + else if (res > 360) res -= 360.0; + + return res; +} + +#if 0 +static void +draw_symbol_text(const char *text, const waypoint *reference) +{ + waypoint wpt; + + if ((reference == NULL) || (text == NULL)) return; + if (*text == '\0') return; + + wpt = *reference; + + wpt.latitude = wpt.latitude + 0.015; + wpt.longitude = wpt.longitude + 0.015; + + draw_symbol_basics(OVL_SYMBOL_TEXT, -1, OVL_COLOR_BLACK, &wpt); + + gbfprintf(fout, "Area=1\n"); + gbfprintf(fout, "Zoom=1\n"); + gbfprintf(fout, "Size=120\n"); + gbfprintf(fout, "Font=3\n"); + gbfprintf(fout, "Dir=100\n"); + gbfprintf(fout, "Text=%s\n", text); +} +#endif + +/**************************************************************************/ + +ff_vecs_t ggv_ovl_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + ggv_ovl_rd_init, + ggv_ovl_wr_init, + ggv_ovl_rd_deinit, + ggv_ovl_wr_deinit, + ggv_ovl_read, + ggv_ovl_write, + NULL, + ggv_ovl_args, + CET_CHARSET_MS_ANSI, 0 +}; + +/**************************************************************************/ -- 2.30.2